//
//  GSFacebook.m
//  AgileNYC
//
//  Created by German on 26.06.14.
//  Copyright (c) 2014 Softlegion. All rights reserved.
//

#import "GSFacebook.h"
#import "SGSUtils.h"
#import "SGSServerManagerConsts.h"



@interface GSFacebook ()

@property (strong, nonatomic) IBOutlet FBLoginView *fbLoginView;
@property (strong, nonatomic) NSString *objectID;
@property (strong, nonatomic) FBSession *session;

@property (copy, nonatomic) GSImageReceivedBlock imageReceivedBlock;

@end

@implementation GSFacebook

- (instancetype)init
{
    self = [super init];
    if (self) {
        [FBLoginView class];
        [FBProfilePictureView class];
        
        [_fbLoginView setReadPermissions:@[@"public_profile",@"email"]];
        [_fbLoginView setDelegate:self];
        
        //FBSession * session = [[FBSession alloc] init];
        //session.appID = facebookAppId;
        
        [FBSettings setDefaultAppID: facebookAppId];
        
        _objectID = nil;
    }
    return self;
}

// This method will be called when the user information has been fetched after login
- (void)loginViewFetchedUserInfo:(FBLoginView *)loginView
                            user:(id<FBGraphUser>)user {
    //self.profilePictureView.profileID = user.id;
    //self.nameLabel.text = user.name;
    
    
    //self.profilePictureView.
}

// You need to override loginView:handleError in order to handle possible errors that can occur during login
- (void)loginView:(FBLoginView *)loginView handleError:(NSError *)error {
    NSString *alertMessage, *alertTitle;
    
    // If the user should perform an action outside of you app to recover,
    // the SDK will provide a message for the user, you just need to surface it.
    // This conveniently handles cases like Facebook password change or unverified Facebook accounts.
    if ([FBErrorUtility shouldNotifyUserForError:error]) {
        alertTitle = @"Facebook error";
        alertMessage = [FBErrorUtility userMessageForError:error];
        
        // This code will handle session closures since that happen outside of the app.
        // You can take a look at our error handling guide to know more about it
        // https://developers.facebook.com/docs/ios/errors
    } else if ([FBErrorUtility errorCategoryForError:error] == FBErrorCategoryAuthenticationReopenSession) {
        alertTitle = @"Session Error";
        alertMessage = @"Your current session is no longer valid. Please log in again.";
        
        // If the user has cancelled a login, we will do nothing.
        // You can also choose to show the user a message if cancelling login will result in
        // the user not being able to complete a task they had initiated in your app
        // (like accessing FB-stored information or posting to Facebook)
    } else if ([FBErrorUtility errorCategoryForError:error] == FBErrorCategoryUserCancelled) {
        GSLog(GSLogWarning, @"[GSFacebook] User cancelled login");
        
        // For simplicity, this sample handles other errors with a generic message
        // You can checkout our error handling guide for more detailed information
        // https://developers.facebook.com/docs/ios/errors
    } else {
        alertTitle  = @"Something went wrong";
        alertMessage = @"Please try again later";
        GSLog(GSLogError, @"Unexpected error:%@", error);
    }
    
    if (alertMessage) {
        [[[UIAlertView alloc] initWithTitle:alertTitle
                                    message:alertMessage
                                   delegate:nil
                          cancelButtonTitle:@"OK"
                          otherButtonTitles:nil] show];
    }
    
    [FBSession.activeSession closeAndClearTokenInformation];
    [self userLoggedOut];
}


-(void) connectToFacebook: (void(^)(BOOL result)) completionBlock {

    GSLog(GSLogInfo, @"FB session state: %d", FBSession.activeSession.state);
    
    if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) {
        GSLog(GSLogInfo, @"Found a cached session");
        [FBSession openActiveSessionWithReadPermissions:@[@"public_profile", @"user_birthday",@"email"]
               allowLoginUI:NO
          completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
              BOOL result;
              if (error) {
                  result = NO;
              } else {
                  result = YES;
              }

              if (completionBlock) {
                  completionBlock(result);
              }
          }];
        
        // If there's no cached session, we will show a login button
    } else if (FBSession.activeSession.state == FBSessionStateOpen
            || FBSession.activeSession.state == FBSessionStateOpenTokenExtended) {
        GSLog(GSLogInfo, @"FB session opened or extended");
        if (completionBlock) {
            completionBlock(YES);
        }
    } else {
        GSLog(GSLogInfo, @"FB session not found");
        [FBSession openActiveSessionWithReadPermissions:@[@"public_profile", @"user_birthday",@"email"]
                                           allowLoginUI:YES
                                      completionHandler:
         ^(FBSession *session, FBSessionState state, NSError *error) {
             BOOL result;
             if (error) {
                 result = NO;
             } else {
                 result = YES;
             }
             if (completionBlock) {
                 completionBlock(result);
             }

         }];

    }

}



- (void)requestUserInfoWithImageHeight:(NSInteger) height
                                 Width:(NSInteger) width
                             onSuccess:(void(^)(NSDictionary * userInfo)) success
                       onImageReceived:(void(^)(NSData* userImage)) imageReceived
                             onFailure:(void(^)(NSError * error)) failure
{
    self.imageReceivedBlock = imageReceived;
    
    [FBRequestConnection startWithGraphPath:@"/me/permissions"
      completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
          if (!error){
              [FBRequestConnection startForMeWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
                  if (!error) {
                      if (success) {
                          success(result);
                      }
                  } else {
                      if (failure) {
                          failure(error);
                      }
                  }
              }];
          } else {
              if (failure) {
                  failure(error);
              }
          }
      }];
    
    [self requestUserImageUrlWithWidth:width Height:height
                          onSuccess:^(NSDictionary *userInfo) {
                              NSDictionary * dict = [userInfo objectForKey:@"data"];
                              NSString * imageURL = [dict objectForKey:@"url"];
                              
                              // Load avatar image asynchronously, in background
                              dispatch_queue_t backgroundQueue =
                              dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
                              
                              dispatch_async(backgroundQueue, ^{
                                  NSData *avatarData = nil;
                                  NSString *imageURLString = imageURL;
                                  if (imageURLString) {
                                      NSURL *imageURL = [NSURL URLWithString:imageURLString];
                                      avatarData = [NSData dataWithContentsOfURL:imageURL];
                                  }
                                  
                                  if (avatarData) {
                                      // Update UI from the main thread when available
                                      dispatch_async(dispatch_get_main_queue(), ^{
                                          //self.userAvatar.image = [UIImage imageWithData:avatarData];
                                          if (imageReceived) {
                                              imageReceived(avatarData);
                                          }
                                      });
                                  } else {
                                      if (imageReceived) {
                                          imageReceived(nil);
                                      }
                                  }
                              });
                          } onFailure:^(NSError *error) {
                              if (imageReceived) {
                                  imageReceived(nil);
                              }
                          }];
    
    
}

- (void)requestUserInfo:(int) reserved
              onSuccess:(void(^)(NSDictionary * userInfo)) success
              onFailure:(void(^)(NSError * error)) failure
{
    [FBRequestConnection startWithGraphPath:@"/me/permissions"
                          completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
                              if (!error){
                                  [FBRequestConnection startForMeWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
                                      if (!error) {
                                          if (success) {
                                              success(result);
                                          }
                                      } else {
                                          if (failure) {
                                              failure(error);
                                          }
                                      }
                                  }];
                              } else {
                                  if (failure) {
                                      failure(error);
                                  }
                              }
                          }];
}

- (void)requestUserImageUrlWithWidth:(NSInteger) width
                              Height:(NSInteger) height
              onSuccess:(void(^)(NSDictionary * userInfo)) success
              onFailure:(void(^)(NSError * error)) failure
{
    NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
                            @"", @"redirect",
                            [NSString stringWithFormat:@"%ld",(long)height], @"height",
                            @"normal", @"type",
                            [NSString stringWithFormat:@"%ld",(long)width], @"width",
                            nil];
    
    [FBRequestConnection startWithGraphPath:@"/me/picture"
                                 parameters:params
                                 HTTPMethod:@"GET"
                          completionHandler:^(FBRequestConnection *connection,NSDictionary * result,NSError *error) {
                              if (!error) {
                                  if (success) {
                                      success(result);
                                  }
                              } else {
                                  if (failure) {
                                      failure(error);
                                  }
                              }
                          }];

}

- (void)openProfilePage:(NSString*) url
                           onSuccess:(void(^)(NSDictionary * userInfo)) success
                           onFailure:(void(^)(NSError * error)) failure
{
    [FBAppCall handleOpenURL:[NSURL URLWithString:url] sourceApplication:nil];
}

/*
// This method will handle ALL the session state changes in the app
- (void)sessionStateChanged:(FBSession *)session state:(FBSessionState) state error:(NSError *)error
{
    // If the session was opened successfully
    if (!error && state == FBSessionStateOpen){
        GSLog(GSLogInfo, @"Session opened");
        // Show the user the logged-in UI
        [self userLoggedIn];
        return;
    }
    if (state == FBSessionStateClosed || state == FBSessionStateClosedLoginFailed){
        // If the session is closed
        GSLog(GSLogWarning, @"Session closed");
        // Show the user the logged-out UI
        [self userLoggedOut];
    }
    
    // Handle errors
    if (error){
        //NSLog(@"Error");
        NSString *alertText;
        NSString *alertTitle;
        // If the error requires people using an app to make an action outside of the app in order to recover
        if ([FBErrorUtility shouldNotifyUserForError:error] == YES){
            alertTitle = @"Something went wrong";
            alertText = [FBErrorUtility userMessageForError:error];
           // [self showMessage:alertText withTitle:alertTitle];
        } else {
            
            // If the user cancelled login, do nothing
            if ([FBErrorUtility errorCategoryForError:error] == FBErrorCategoryUserCancelled) {
                GSLog(GSLogWarning, @"User cancelled login");
                
                // Handle session closures that happen outside of the app
            } else if ([FBErrorUtility errorCategoryForError:error] == FBErrorCategoryAuthenticationReopenSession){
                alertTitle = @"Session Error";
                alertText = @"Your current session is no longer valid. Please log in again.";
                //[self showMessage:alertText withTitle:alertTitle];
                
                // For simplicity, here we just show a generic message for all other errors
                // You can learn how to handle other errors using our guide: https://developers.facebook.com/docs/ios/errors
            } else {
                //Get more error information from the error
                NSDictionary *errorInformation = [[[error.userInfo objectForKey:@"com.facebook.sdk:ParsedJSONResponseKey"] objectForKey:@"body"] objectForKey:@"error"];
                
                // Show the user an error message
                alertTitle = @"Something went wrong";
                alertText = [NSString stringWithFormat:@"Please retry. \n\n If the problem persists contact us and mention this error code: %@", [errorInformation objectForKey:@"message"]];
                //[self showMessage:alertText withTitle:alertTitle];
            }
        }
        // Clear this token
    }
}
*/
// Show the user the logged-out UI
- (void)userLoggedOut
{
    GSLog(GSLogInfo, @"User logged out from facebook");
}

// Show the user the logged-in UI
- (void)userLoggedIn
{
    GSLog(GSLogInfo, @"User logged in to facebook");
}



#pragma mark - Connect to facebook without SDk

/*
 -(void) loginWithFacebook:(GSUser*) currentUser
 onComplete: (GSCompletionBlock) completionBlock
 {
 
 self.currentUser = currentUser;
 self.loginCompletionBlock = completionBlock;
 
 NSString * urlString = [NSString stringWithFormat:
 @"https://www.facebook.com/dialog/oauth?"
 "client_id=%@"
 "&redirect_uri=%@"
 "&state=%@"
 "&response_type=%@"
 "&scope=%@"
 ,facebookAppId
 ,facebookRedirectURL
 ,facebookStateString
 ,@"token"
 //@"public_profile,email"];
 ,@"public_profile, user_birthday, user_location, user_activities, user_website, user_photos, user_about_me, email"];
 
 self.currentAuthHost = [[NSURL URLWithString:facebookRedirectURL] host];
 //self.currentToken = currentUser.facebookToken;
 self.currentTokenKey = facebookTokenKey;
 self.currentExpiredKey = facebookExpiredKey;
 self.currentUserIDKey = facebookUserIdKey;
 self.currentErrorKey = facebookErrorKey;
 
 //urlString = @"http://www.google.com/";
 
 NSString* webUrlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
 
 [self showExternalLoginDialogWithURL:webUrlString caption:@"Login to Facebook"];
 }
 */
/*
 -(void) getUserFromFacebook:(GSUser*) currentUser
 onComplete: (GSCompletionBlock) completionBlock {
 
 self.currentUser = currentUser;
 
 [self initRequestManagerWithURL:facebookURL];
 
 NSDictionary * params = [NSDictionary dictionaryWithObjectsAndKeys:
 currentUser.tokenFacebook,@"access_token",
 nil];
 
 //[self startSpinnerOnView:nil];
 
 [self.requestOperationManager GET:@"me"
 parameters:params
 success:^(AFHTTPRequestOperation *operation, NSDictionary * responseObject) {
 //GSLog(GSLogInfo, @"FB JSON: %@", responseObject);
 //GSLog(GSLogInfo, @"FB URL: %@ ", operation.request.URL);
 
 for (NSString * key in [responseObject allKeys]) {
 
 if ([key isEqualToString:@"first_name"]) {
 currentUser.firstName = [responseObject objectForKey:key];
 } else if ([key isEqualToString:@"last_name"]) {
 currentUser.lastName = [responseObject objectForKey:key];
 } else if ([key isEqualToString:@"id"]) {
 //currentUser.facebookToken.userID = [responseObject objectForKey:key];
 } else if ([key isEqualToString:@"email"]) {
 currentUser.eMail = [responseObject objectForKey:key];
 } else if ([key isEqualToString:@"website"]) {
 currentUser.webSite = [responseObject objectForKey:key];
 } else if ([key isEqualToString:@"location"]) {
 NSDictionary * locDic = [responseObject objectForKey:key];
 currentUser.city = [locDic objectForKey:@"name"];
 }
 
 }
 
 if (completionBlock) {
 completionBlock(YES,nil, operation.response.statusCode);
 }
 
 [self stopSpinner];
 }
 failure:^(AFHTTPRequestOperation *operation, NSError *error) {
 if (completionBlock) {
 completionBlock(NO,error,operation.response.statusCode);
 }
 
 [self stopSpinner];
 }];
 }
 */


@end
